﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Parser
{
    public abstract class DFA<LexState, TokenType>
    {
        /// <summary>
        /// 初始化词法分析状态
        /// </summary>
        /// <returns></returns>
        protected abstract IDictionary<LexState, DFAState<TokenType>> InitalizeLexStateTable();        

        /// <summary>
        /// 初始化词法分析状态图
        /// </summary>
        protected abstract void InitalizeLexState();

        /// <summary>
        /// 获取起始状态
        /// </summary>
        /// <returns></returns>
        protected abstract DFAState<TokenType> GetStartState();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public IEnumerable<TokenBase<TokenType>> Lex(string document)
        {
            InitalizeLexState();

            var collection = new List<TokenBase<TokenType>>();
            var stateStack = new StateStack<TokenType>();
            var stream = new CharacterStream(document);
            var state = GetStartState();
            TokenBase<TokenType> last = null,now = null;

            while (!stream.EndOfFile) {
                if (state != null) {                    
                    state = state.Action(collection, stateStack, stream, state, ref last, ref now);
                }
                else {
                    //避免空状态造成的死循环
                    stream.Move(1);
                }
            }

            return collection;
        }
    }
}
